KeyNavigatorBehavior
The KeyNavigatorBehavior is the built in Java 3D keyboard navigation class รป part of the utilities package. The KeyNavigatorBehavior is very easy to use and it typically just consists of: creating a KeyNavigatorBehavior object and passing in the TransformGroup that the behavior should modify, setting the scheduling bounds for the behavior, ensuring the ALLOW_TRANSFORM_WRITE capability bit is set on the TransformGroup and adding the KeyNavigatorBehavior to the scenegraph.
create the TransformGroup that the Key behavior will effect
TransformGroup zoomTg = new TransformGroup();
zoomTg.setCapability( TransformGroup.ALLOW_TRANSFORM_WRITE );
zoomTg.setCapability( TransformGroup.ALLOW_TRANSFORM_READ );
create the Key behavior and add to the scenegraph
KeyNavigatorBehavior key = new KeyNavigatorBehavior( zoomTg );
key.setSchedulingBounds( createApplicationBounds() );
key.setEnable( true );
objRoot.addChild( key );
The Keyboard controls for the KeyNavigatorBehavior are implemented in the KeyNavigator class, which performs all the matrix modifications based on key presses. The KeyNavigator class has a fairly sophisticated implementation that includes a large number of movement key combinations and acceleration of movement.
The key events that the KeyNavigator class handles are:
DOWN_ARROW |
move backwards |
UP_ARROW |
move forwards |
RIGHT_ARROW |
rotate right |
LEFT_ARROW |
rotate left |
PAGE_UP |
rotate upwards |
PAGE_DOWN |
rotate downwards |
ALT + RIGHT_ARROW |
move right |
ALT + LEFT_ARROW |
move left |
ALT + PAGE_UP |
move upwards |
ALT+ PAGE_DOWN |
move downwards |
EQUALS (HOME_NOMINAL) |
stop movement |
SHIFT |
fast movement, rotation and scale |
SHIFT + META |
slow movement, rotation and scale |
PLUS_SIGN |
increase Scale |
MINUS_SIGN |
decrease Scale |
Writing a Simple Keyboard Behavior
Simple Keyboard processing is easy to accomplish, for example, the class below simply modifies a TransformGroup in response to presses of the left and right arrow keys.
public class CarSteering extends Behavior
{
private WakeupOnAWTEvent wakeupOne = null;
private WakeupCriterion[] wakeupArray = new WakeupCriterion[1];
private WakeupCondition wakeupCondition = null;
private final float TRANSLATE_LEFT = -0.05f;
private final float TRANSLATE_RIGHT = 0.05f;
TransformGroup m_TransformGroup = null;
public CarSteering( TransformGroup tg )
{
m_TransformGroup = tg;
wakeupOne = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
wakeupArray[0] = wakeupOne;
wakeupCondition = new WakeupOr(wakeupArray);
}
Override Behavior's initialize method to setup wakeup criteria
public void initialize()
{
Establish initial wakeup criteria
wakeupOn(wakeupCondition);
}
Override Behavior's stimulus method to handle the event.
public void processStimulus(Enumeration criteria)
{
WakeupOnAWTEvent ev;
WakeupCriterion genericEvt;
AWTEvent[] events;
while (criteria.hasMoreElements())
{
genericEvt = (WakeupCriterion) criteria.nextElement();
if (genericEvt instanceof WakeupOnAWTEvent)
{
ev = (WakeupOnAWTEvent) genericEvt;
events = ev.getAWTEvent();
processAWTEvent(events);
}
}
Set wakeup criteria for next time
wakeupOn(wakeupCondition);
}
Process a keyboard event
private void processAWTEvent(AWTEvent[] events)
{
for( int n = 0; n < events.length; n++)
{
if( events[n] instanceof KeyEvent)
{
KeyEvent eventKey = (KeyEvent) events[n];
if( eventKey.getID() == KeyEvent.KEY_PRESSED )
{
int keyCode = eventKey.getKeyCode();
int keyChar = eventKey.getKeyChar();
Vector3f translate = new Vector3f();
Transform3D t3d = new Transform3D();
m_TransformGroup.getTransform( t3d );
t3d.get( translate );
switch (keyCode)
{
case KeyEvent.VK_LEFT:
translate.x += TRANSLATE_LEFT;
break;
case KeyEvent.VK_RIGHT:
translate.x += TRANSLATE_RIGHT;
break;
}
t3d.setTranslation( translate );
m_TransformGroup.setTransform( t3d );
}
}
}
}
}